package org.keyintegrity.webbeans;

import java.util.Collections;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.tapestry.BaseComponent;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.components.Block;
import org.keyintegrity.webbeans.utils.BeanUtils;

public abstract class BeanEditor extends BaseComponent {
    
    private static final Logger logger = Logger.getLogger(BeanEditor.class);
    
    public abstract void setBean(Object bean);
    public abstract Object getBean();
    
    public abstract void setBeanFieldName(String name);
    public abstract String getBeanFieldName();
    
    public abstract BeanEditorDecorator getDecorator();
    
    public abstract boolean isReadOnly();
    public abstract void setReadOnly(boolean readOnly);
    
    public abstract BeanEditorTypeMappings getParent();
    
    @Override
    protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
        if (logger.isDebugEnabled()) {
            logger.debug("renderComponent()");
            logger.debug("rewinding = " + cycle.isRewinding());
            logger.debug("parent    = " + getParent());
            logger.debug("parent.beanFieldName = " + 
                    (getParent() != null ? getParent().getBeanEditor().getBeanFieldName() : "?"));
        }
        super.renderComponent(writer, cycle);
    }
    
    public BeanEditor getInstance() {
        return this;
    }
    
    public boolean isRenderXml() {
        return false;
    }
    
    @SuppressWarnings("unchecked")
    public List<String> getBeanFieldNames() {
        if (getBean() == null) {
            return Collections.EMPTY_LIST;
        }
        return BeanUtils.getBeanFieldNames(getBean().getClass()); 
    }

    public Class getBeanFieldType() {
        return BeanUtils.getBeanFieldType(getBean().getClass(), getBeanFieldName());
    }
    
    public Block getNestedBeanEditor() {
        IRequestCycle cycle = getPage().getRequestCycle();
        
        String nbePageName = getNamespace().getId() + ":BeanEditorPool"; 
         
        BeanEditorPool nbe = (BeanEditorPool) cycle.getPage(nbePageName);
        
        return nbe.acquireBeanEditorBlock(this, getBeanFieldName());
    }
    
    /*
     * BeanEditorDecorator Wrapper
     */

    public String getBeanFieldLabel() {
        HTMLString html = new HTMLString();
        html.getHtml().append(getBeanFieldName());
        
        if (getDecorator() != null) {
            getDecorator().renderBeanFieldLabel(getBean(), html);
        }
        
        return html.toString();
    }
    
    public String getHeaderMessage() {
        HTMLString header = null;
        
        if (getDecorator() != null) {
            header = getDecorator().renderHeader(getBean());
        }
        
        return header == null ? null : header.toString();
    }
    
}
